package com.lyh.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.config.WebIniSecurityManagerFactory;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 这是Shiro配置类
 */
@Configuration
public class ShiroConfig {

    //1.创建shiroFilter 负责拦截所有请求
    @Bean(name = "shiroFilterFactoryBean")
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("mySecurityManager") DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //给filter设置安全管理器
        bean.setSecurityManager(securityManager);

        //配置系统受限资源
        /**
         * anon: 无需认证就可以访问
         * authc: 必须认证才可以访问
         * user: 必须有 记住我功能才能使用
         * perms: 拥有对某个资源的权限才能访问
         * role: 拥有某个角色权限才能访问
         */
        Map<String,String> map = new LinkedHashMap<>();
        map.put("/test","anon");
        //放行首页
        map.put("/index","anon");
        map.put("/","anon");
        //放行用户注册和登陆 登出
        map.put("/login","anon");
        map.put("/register","anon");
        map.put("/user/login","anon");
        map.put("/user/register","anon");
        map.put("/public/register","anon");
        map.put("/user/logout","anon");
        //放行用户名查重
        map.put("/user/checkName/**","anon");
        //放行权限登陆页面
        map.put("/haveToLogin/**","anon");

        //放行指导， 跟首页查询功能
        map.put("/guide","anon");
        map.put("/guide/**","anon");

        //放行激活页面
        map.put("/user/active/**","anon");
        map.put("/activeMail/**","anon");
        //放行提示信息页面
        map.put("/msg/**","anon");

        //放行静态资源和请求验证码
        map.put("/public/getImage","anon");
        map.put("/favicon.ico","anon");
        map.put("/components/**","anon");
        map.put("/webjars/**","anon");
        map.put("/css/**","anon");
        map.put("/js/**","anon");
        map.put("/img/**","anon");

        map.put("/**","authc");//默认访问全部资源都需要认证, 除了上面的anon资源
        bean.setFilterChainDefinitionMap(map);
        bean.setLoginUrl("/haveToLogin/1");//如果没有权限就跳转到登陆页面

        return bean;
    }

    //2.创建安全管理器
    @Bean(name = "mySecurityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("customizeRealm") CustomizeRealm realm){

        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //给安全管理器设置
        securityManager.setRealm(realm);
        return securityManager;
    }

    //3.创建自定义realm, 定义加密方式
    @Bean(name = "customizeRealm")
    public CustomizeRealm getCustomizeRealm(){

        CustomizeRealm realm = new CustomizeRealm();
        //创建加密方式, salt在自定义Realm中设置
        HashedCredentialsMatcher hash = new HashedCredentialsMatcher();
        //使用md5, 对客户端传来的数据加密
        hash.setHashAlgorithmName("md5");
        //散列次数
        hash.setHashIterations(1024);

        realm.setCredentialsMatcher(hash);//设置加密方式

        return realm;
    }

    //加入shiro标签方言
    @Bean(name = "shiroDialect")
    public ShiroDialect shiroDialect(){
        return new ShiroDialect();
    }

}
